#include "collisioncamera.h"
#include "manipulatorbase.h"
#include "Transform.h"
#include "actorbase.h"
#include "scene.h"

namespace ControlCenter
{
	CollisionCamera::CollisionCamera(ManipulatorBase* manipulatorbase,const QString& name ):Transformable(NULL,name)
	{
		if(manipulatorbase!=NULL)
			_manipulatorBaseVector.push_back(manipulatorbase);
		setCollisionSphere(0.3f);
	}

	CollisionCamera::~CollisionCamera()
	{}

	void CollisionCamera::onMessage(MessageData* data)
	{
		if (data->message == SYSTEM_MESSAGE_COLLISION)
		{
			CoreBase::Scene::CollisionData* cd = static_cast<CoreBase::Scene::CollisionData* >( data->userData );
			CoreBase::Transformable*  transform1 = cd->mBodies[0];
			CoreBase::Transformable*  transform2 = cd->mBodies[1];
			if((transform1 == this || transform2 == this) && transform1->getName()!=transform2->getName())
			{
				for(int i=0;i<_manipulatorBaseVector.size();++i)
				{
					_manipulatorBaseVector.at(i)->collisionEvent(cd);
				}
			}
		}
		else if (data->message == SYSTEM_MESSAGE_POST_ENENT_TRAVERSAL)
		{
			for(int i=0;i<_manipulatorBaseVector.size();++i)
			{
				_manipulatorBaseVector.at(i)->computeNewPositionPerFrame();
			}
		}
		else if (data->message == SYSTEM_MESSAGE_PRE_FRAME)
		{
			for(int i=0;i<_manipulatorBaseVector.size();++i)
			{
				_manipulatorBaseVector.at(i)->computeInverseMatrixPerFrame();
			}
		}
	}

	void CollisionCamera::addManipulator(ManipulatorBase* manipulatorbase)
	{
		if(!_manipulatorBaseVector.contains(manipulatorbase))
			_manipulatorBaseVector.push_back(manipulatorbase);
	}

	void CollisionCamera::removeManipulator(ManipulatorBase* manipulatorbase)
	{
		if(_manipulatorBaseVector.contains(manipulatorbase))
			_manipulatorBaseVector.remove(_manipulatorBaseVector.indexOf(manipulatorbase));
	}

	void CollisionCamera::clearAllManipulator()
	{
		_manipulatorBaseVector.clear();
	}

	unsigned int CollisionCamera::workManipulatorSize()
	{
		return _manipulatorBaseVector.size();
	}

	void CollisionCamera::setTransformable(const osg::Vec3& translation,const osg::Vec3& rota)
	{
		CoreBase::Transform trans;
		setTransform(trans,CoreBase::Transformable::REL_CS);
		_oldTranslation = trans.GetTranslation();
		trans.getRotation(_oldRotation);
		osg::Vec3 hpr = rota*180.0f/osg::PI;
		if (hpr.x() < 0.0f)
			hpr.x() += 360.0f;
		if (hpr.x() > 360.0f)
			hpr.x() -= 360.0f;

		if (hpr.y() < 0.0f)
			hpr.y() += 360.0f;
		if (hpr.y() > 360.0f)
			hpr.y() -= 360.0f;

		if (hpr.z() < 0.0f)
			hpr.z() += 360.0f;
		if (hpr.z() > 360.0f)
			hpr.z() -= 360.0f;

		trans.setTranslation(translation[0], translation[1], translation[2]);
		trans.setRotation(osg::Vec3(hpr[2],hpr[0],hpr[1]));
		setTransform(trans,CoreBase::Transformable::REL_CS);
	}

	void CollisionCamera::backOldTransformable()
	{
		setTransformable(_oldTranslation,_oldRotation);
	}
}